<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>检测静音并分割音频</title>
</head>

<body>
    <h1>检测静音并分割音频</h1>
    <button class="record-btn">开始录音</button>
    <ul id="fileList"></ul>
    <pre id="silenceLog"></pre>
    <script>
    if (window.navigator.mediaDevices.getUserMedia) {
        const constraints = { audio: true };
        window.navigator.mediaDevices.getUserMedia(constraints).then(stream => {
            console.log("授权成功！");
            //绑定点击按钮
            const recordBtn = document.querySelector(".record-btn");
            const mediaRecorder = new MediaRecorder(stream);
            recordBtn.onclick = () => {
                mediaRecorder.start();
                console.log("录音中...");
            };
            recordBtn.onclick = () => {
                if (mediaRecorder.state === "recording") {
                    mediaRecorder.stop();
                    recordBtn.textContent = "开始录音";
                    console.log("录音结束");
                } else {
                    mediaRecorder.start();
                    console.log("录音中...");
                    recordBtn.textContent = "停止录音";
                }
                console.log("录音器状态：", mediaRecorder.state);
            };
            this.chunks = [];
            mediaRecorder.ondataavailable = (e) => {
                console.log(e.data, 'e')
                this.chunks.push(e.data);
            };
            mediaRecorder.onstop = e => {
                console.log(111111111)
                const reader = new FileReader();
                reader.onload = async (event) => {
                    //设置采样率为16000，不设置会根据浏览器自己来判断设置
                    const audioContext = new(window.AudioContext || window.webkitAudioContext)({ sampleRate: 16000 });
                    const arrayBuffer = event.target.result;
                    const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
                    //设置wav的头
                    const wavData = encodeWAV(audioBuffer);
                    const wavBlob = new Blob([wavData], { type: 'audio/wav' });
                    const formData = new FormData();
                    formData.append('file', wavBlob, 'recording.wav');
                    //生成本地的访问地址
                    var audioURL = window.URL.createObjectURL(wavBlob);
                    console.log(audioURL, 'audioURL')
                    this.chunks = [];
                    console.log('Recorded audio URL:', audioURL)
                    const li = document.createElement('li');
                    const a = document.createElement('a');
                    a.href = audioURL;
                    a.download = `recording.wav`;
                    a.textContent = `recording.wav`;
                    li.appendChild(a);
                    document.getElementById('fileList').appendChild(li);
                    a.click();

                };
                reader.readAsArrayBuffer(this.chunks[0]);

                function encodeWAV(audioBuffer) {
                    const numOfChan = audioBuffer.numberOfChannels,
                        length = audioBuffer.length * numOfChan * 2 + 44,
                        buffer = new ArrayBuffer(length),
                        view = new DataView(buffer),
                        sampleRate = audioBuffer.sampleRate,
                        samples = audioBuffer.getChannelData(0);
                    let offset = 0;
                    const writeString = (str) => {
                        for (let i = 0; i < str.length; i++) {
                            view.setUint8(offset++, str.charCodeAt(i));
                        }

                    };
                    writeString('RIFF');
                    view.setUint32(offset, length - 8, true);
                    offset += 4;
                    writeString('WAVE');
                    writeString('fmt ');
                    view.setUint32(offset, 16, true);
                    offset += 4;
                    view.setUint16(offset, 1, true);
                    offset += 2;
                    view.setUint16(offset, numOfChan, true);
                    offset += 2;
                    view.setUint32(offset, sampleRate, true);
                    offset += 4;
                    view.setUint32(offset, sampleRate * 2 * numOfChan, true);
                    offset += 4;
                    view.setUint16(offset, numOfChan * 2, true);
                    offset += 2;
                    view.setUint16(offset, 16, true);
                    offset += 2;
                    writeString('data');
                    view.setUint32(offset, length - offset - 8, true);
                    offset += 4;
                    for (let i = 0; i < samples.length; i++) {
                        view.setInt16(offset, samples[i] * 0x7FFF, true);
                        offset += 2;
                    }
                    return view;
                }
            };

        }).catch(function(err) {
            // 处理错误情况
            console.error('Error accessing media devices:', err)

        });

    } else {
        console.error("浏览器不支持 getUserMedia");
    }
    </script>
</body>

</html>
